import Vue from 'vue'
import { on, hasClass } from './dom'

const nodeList = []
const ctx = '@@clickoutsideContext'

!Vue.prototype.$isServer && on(document, 'click', e => {
  nodeList.forEach(node => {
    var argument = node[ctx].argument
    if (hasClass(e.target, argument)) { return }
    node[ctx].documentHandler(e)
  })
})

/**
 * v-clickoutside
 * @desc 点击元素外面才会触发的事件
 * @example
 * ```vue
 * <div v-element-clickoutside="handleClose">
 * ```
 */
export default {
  bind(el, binding, vnode) {
    const id = nodeList.push(el) - 1

    const documentHandler = function(e) {
      if (!vnode.context ||
                el.contains(e.target) ||
                (vnode.context.popperElm &&
                vnode.context.popperElm.contains(e.target))) return

      if (binding.expression &&
                el[ctx].methodName &&
                vnode.context[el[ctx].methodName]) {
        vnode.context[el[ctx].methodName]()
      } else {
        el[ctx].bindingFn && el[ctx].bindingFn()
      }
    }
    el[ctx] = {
      id,
      documentHandler,
      methodName: binding.expression,
      bindingFn: binding.value,
      argument: binding.arg
    }
  },

  update(el, binding) {
    el[ctx].methodName = binding.expression
    el[ctx].bindingFn = binding.value
  },

  unbind(el) {
    const len = nodeList.length

    for (let i = 0; i < len; i++) {
      if (nodeList[i][ctx].id === el[ctx].id) {
        nodeList.splice(i, 1)
        break
      }
    }
  }
}
